%!TEX root = ./main.tex

\chapter{The Inter OS-application Communication Library}

\lettrine{I}nter OS-application Communication library is an API initially dedicated to communications between tasks from different OS-applications in multicore systems. However, it could also be used for communications between tasks from a same OS-Application. In the fallowing, Inter OS-application Communication will be denoted IOC.
This chapter presents the IOC configuration and API.
Implementation details as well as examples of utilization are provided.

\section{IOC declaration in OIL}

The IOC configuration is performed using OIL. Parameters such as IOC name, the type of manipulated data, the kind of communication (queued or last is best) and informations about sender/receiver are mandatory. The syntax is presented below using tow example.

Let us consider the case where a task A (as part of OS-application \textit{os-app1}) sends a data to a task B (as part of OS-application \textit{os-app2}). 
In the first case, we consider a last is best semantic communication where only one data of type u8 is sent.
In the second case, we consider a queued semantic communication where a data of type u8 and a data of type \textit{mytype} (defined by user) are sent. It is worth noting that this type have to be defined by user un the file \textit{ioc_types.h} at the root of the project directory.

\textit{mytype} can be defined like this:

\begin{lstlisting}[language=C]
struct mytype {
  u8	  a;
  u8	  b,
}
\end{lstlisting}

\begin{lstlisting}[language=OIL]

/* LAST_IS_BEST semantic */

IOC com_A_to_B_last_is_best {
  DATATYPENAME u8 {
    DATATYPEPROPERTY = DATA;
  };
  SEMANTICS = LAST_IS_BEST {
    INIT_VALUE_SYMBOL = AUTO;
  };
  RECEIVER rcv {
    RCV_OSAPPLICATION = os-app2;
    RECEIVER_PULL_CB = AUTO;
    ACTION = NONE;
  };
  SENDER sender0 {
    SENDER_ID = 0;
    SND_OSAPPLICATION = os-app1;
  };
}; 

/* QUEUED semantic */

IOC com_A_to_B_queued {
  DATATYPENAME u8 {
    DATATYPEPROPERTY = DATA;
  };
  DATATYPENAME mytype {
    DATATYPEPROPERTY = REFERENCE;
  };
  SEMANTICS = QUEUED {
    BUFFER_LENGTH = 2;
  };
  RECEIVER rcv {
    RCV_OSAPPLICATION = os-app2;
    RECEIVER_PULL_CB = AUTO;
    ACTION = NONE;
  };
  SENDER sender0 {
    SENDER_ID = 0;
    SND_OSAPPLICATION = os-app1;
  };
}; 

\end{lstlisting}

The DATATYPENAME parameter defines the name of the data type to be transferred. A file named \textit{ioc_types.h} should be created by user in order to defined new types, if any. The associated property specifies if the data is passed to sending functions by reference or by value. It is worth noting that it is possible to specify many DATATYPENAME as illustrated with the second example. In that case, the applicative sending function should have as many parameters as the number of DATATYPE specify in the OIL file. 
In case of a last is best semantic, the INIT_VALUE_SUMBOL defines the initial data value. It can be set to AUTO is there are no initial value. Otherwise, the INIT_VALUE_SYMBOL is a string type defined by user and the function \textit{IOC_init()} has to be called at the beginning of application. In case of a queued semantic, only a BUFFER_LENGTH has to be specified.
The receiver configuration requires the setting of the target OS-application (RCV_OSAPPLICATION), the king of task notification used when the message has arrived (ACTION = ACTIVATETASK, SETEVENT or NONE) (not functional at the moment) and the callback function to call (not functional at the moment).
The sender configuration require the SENDER_ID, as an integer, and the sender OS-application (SND_OSAPPLICATION). 

\section{Implementation}

The IOC is divided in two set of source files. First, the APIs (part of the OS) containing kernel functions are generic. They can be found in \textit{ioc/} directory. Second, specific files for the IOC configuration are generated. The IOC API is very closed to internal communication library and will not be detailed here. Let us now detailed what is generated in \textit{tpl_ioc_api_config.c}.

In case of the last is best communication (example 1), the sending operation is performed by the call of \textit{IocWrite_IocName()} function and the receiving operation, by the call of the function \textit{IocRead_IocName()}. These functions have to be called directly by user in applicative functions. The generated part of the API transmit the request to the kernel. Let us now illustrated the generated code for the first example.

\begin{lstlisting}[language=C]

FUNC(Std_ReturnType, OS_CODE) IocWrite_com_A_to_B_last_is_best(
  VAR(u8, AUTOMATIC) IN0 /* one data is send */
)
{
  /* only one data implies only one element in the message table */
  VAR(tpl_ioc_message, AUTOMATIC) message[1]; 
  VAR(Std_ReturnType, AUTOMATIC) result;

  /* Fill in the message structure with the data address and its size */
  message[0].data=(tpl_ioc_data *)&IN0;
  message[0].length=sizeof(u8);
  
  /* Call the kernel function */
  result = IOC_Write(0, message); 
  
  return result;
}

FUNC(Std_ReturnType, OS_CODE) IocRead_com_A_to_B_last_is_best(
  P2VAR(u8, AUTOMATIC, OS_APPL_DATA) IN0
)
{
  VAR(tpl_ioc_message, AUTOMATIC) message[1];
  VAR(Std_ReturnType, AUTOMATIC) result;

  message[0].data=(tpl_ioc_data *)IN0;
  message[0].length=sizeof(u8);
  
  /* Call the kernel function */
  result = IOC_Read(0, message);
  
  return result;
}

\end{lstlisting}


In the case of a queued communication, the sending and receiving operations are performed by the call of \textit{IocSend_IocName()} and \textit{IocReceive_IocName()} respectively. Generated functions would be of the same form that in last is best case.

Finally, it is possible that several senders send a same data. In that case, many senders can be defined during the OIL configuration. In the applicative functions, user have to call API functions of type \textit{IocWrite_IocName_SenderName() or IocSend_IocName_SenderName()} when sending a message.